/**
 * @author Created by qiush on 2017-08-30.
 */

'use strict';

const fs = require('fs');
const fse = require('fs-extra');
const path = require('path');
const uglify = require('uglify-es');

const packager = require('electron-packager');

function readdir(dir) {
  return new Promise((resolve, reject) => {
    fs.readdir(dir, (err, files) => {
      if (err) {
        reject(err);
      } else {
        resolve(files);
      }
    });
  });
}

function readfile(file) {
  return new Promise((resolve, reject) => {
    fs.readFile(file, 'utf-8', (err, data) => {
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    });
  });
}

function writefile(file, data) {
  return new Promise((resolve, reject) => {
    fse.outputFile(file, data, 'utf-8', (err) => {
      if (err) {
        reject(err);
      } else {
        resolve(true);
      }
    });
  });
}

function stat(file) {
  return new Promise((resolve, reject) => {
    fs.stat(file, (err, stats) => {
      if (err) {
        reject(err);
      } else {
        resolve(stats);
      }
    });
  });
}

function copy(src, dist) {
  return new Promise((resolve, reject) => {
    fse.copy(src, dist, (err) => {
      if (err) {
        reject(err);
      } else {
        resolve(true);
      }
    });
  });
}

async function minify(file, options) {
  try {
    const data = await readfile(file);

    const result = uglify.minify(data, {
      ie8: false,
      ecma: 6,
      output: {
        comments: false,
        beautify: false
      },
      warnings: false,
      sourceMap: {
        url: `${path.basename(file, '.js')}.js.map`
      }
    });
    console.info(file);
    console.info(result);
    console.info('');

    const destFile = path.join(options.dist, file);
    const writeFilePromise = await writefile(destFile, result.code);
    // const writeMapPromise = await writefile(`${destFile}.map`, result.map);

    return Promise.all([writeFilePromise, /*writeMapPromise*/]);

  } catch (e) {
    console.error(e);
  }
}

async function minifyDir(dir, options) {
  try {
    const files = await readdir(dir);

    const promises = files.map(async file => {
      const filePath = path.join(dir, file);
      const fileStat = await stat(filePath);
      if (fileStat.isFile()) {
        await minify(filePath, options);
      } else if (fileStat.isDirectory()) {
        await minifyDir(filePath, options);
      }
    });

    return Promise.all(promises);

  } catch (e) {
    console.error(e);
  }
}

function packageApp() {
  return new Promise((resolve, reject) => {
    packager({
      dir: 'app',
      out: 'dist',
      all: true,
      asar: true,
      overwrite: true
    }, (err, appPaths) => {
      if (err) {
        reject(err);
      } else {
        resolve(appPaths);
      }
    });
  });
}

async function doPackage() {
  const minifyOptions = {
    dist: 'app'
  };
  await minifyDir('src/main', minifyOptions);

  const packageJson = 'package.json';
  await copy(packageJson, path.join(minifyOptions.dist, packageJson));

  await packageApp();
}

try {
  doPackage().then(() => {
    console.log('package is done');
  });
} catch (e) {
  console.info(e);
}
